package org.jheuristics.ga.operators.selectors;

import java.util.Comparator;

import org.epanetgrid.otimizacao.log.AGLogger;
import org.epanetgrid.otimizacao.util.OtimizacaoUtil;
import org.jheuristics.Individual;
import org.jheuristics.ga.DefaultPopulation;
import org.jheuristics.ga.GAConfig;
import org.jheuristics.ga.GAStatus;
import org.jheuristics.ga.Population;
import org.jheuristics.ga.operators.Selector;


/**
 * TODO
 *
 * @author Marcell Manfrin, marcell at ourgrid.org, 2005
 */
public abstract class AbstractTournamentSelection implements Selector {
	private Comparator comparator;

	/**
	 * TODO
	 */
	public AbstractTournamentSelection() {
		super();
	}

	/**
	 * TODO
	 *
	 * @param comparator
	 */
	public AbstractTournamentSelection(Comparator comparator) {
		this();
		setComparator(comparator);
	}

	/**
	 * TODO
	 *
	 * @param population
	 * @param howMany
	 * @param status
	 * @param config
	 * @return
	 * @see org.jheuristics.ga.operators.Selector#select(org.jheuristics.ga.Population, int, org.jheuristics.ga.GAStatus, org.jheuristics.ga.GAConfig)
	 */
	public Individual[] select(Population population, int howMany, GAStatus status, GAConfig config) {
		AGLogger.getInstance().debug("******** Iniciando operador de seleção*****************");
		
        if (null == population) {
			// TODO: ERROR MSG
			throw new NullPointerException();
        }
        if (0 > howMany) {
			// TODO: ERROR MSG
			throw new IllegalArgumentException();
        }
        if (null == config) {
			// TODO: ERROR MSG
			throw new NullPointerException();
        }
        if (0 == population.size()) {
			// TODO: ERROR MSG
			throw new IllegalArgumentException();
        }
        Individual[] individuals = population.toIndividualArray();
        Population result = new DefaultPopulation();
        
//        SPLogger.getInstancia().log(SPLogger.OTIMIZACAO, SPLogger.DEBUG, "TORNEIO INICIO========================");
//        SPLogger.getInstancia().log(SPLogger.OTIMIZACAO, SPLogger.DEBUG, "howMany= "+howMany);
        for (int i = 0; i < howMany; i++) {
        	result.addIndividual(select(individuals, status, config));
        }
        
        StringBuffer buffer = new StringBuffer("População gerada pelo torneio: ");
        buffer.append(result.size());
        buffer.append("\n");
        buffer.append(OtimizacaoUtil.format(result));
//        for (int i = 0; i < result.size(); i ++) {
//			buffer.append(result.getIndividual(i));
//			buffer.append("\n");
//		}
        
        AGLogger.getInstance().debug(buffer);
        
        AGLogger.getInstance().debug("******** Iniciando operadores de reprodução*****************");
		
		return result.toIndividualArray();
	}

	/**
	 * TODO
	 *
	 * @param individuals
	 * @param status
	 * @param config
	 * @return
	 */
	protected abstract Individual select(Individual[] individuals, GAStatus status, GAConfig config);

	/**
	 * TODO
	 *
	 * @return
	 */
	public Comparator getComparator() {
		return comparator;
	}

	/**
	 * TODO
	 *
	 * @param comparator
	 */
	public void setComparator(Comparator comparator) {
		this.comparator = comparator;
	}

}
